﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace AdvancedException27thMay
{
    [Version(3)]
    class Student
    {
        private int age;
        private char gender;
        private string name;
        private int ssn;
        private int klass;

        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                ValidateAge(value);
                age = value;
            }
        }

        public char Gender
        {
            get
            {
                return gender;
            }
            set
            {
                ValidateGender(value);
                gender = value;
            }
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                ValidateName(value);
                name = value;
            }
        }

        public int Ssn
        {
            [Version(1423)]
            get
            {
                return ssn;
            }
            set
            {
                ValidateSsn(value);
                ssn = value;
            }
        }

        public int Klass
        {
            get
            {
                return klass;
            }
            set
            {
                ValidateClass(value);
                klass = value;
            }
        }

        private void Validate(string name, char gender, int age, int klass, int ssn)
        {
            ValidateAge(age);
            ValidateName(name);
            ValidateClass(klass);
            ValidateSsn(ssn);
            ValidateGender(gender);
        }

        private void ValidateAge(int age)
        {
            if (age > 18 || age < 7)
                throw new InvalidStudentException("Age must me in range [7..18]");
        }

        private void ValidateName(string name)
        {
            if (name.Length > 50 || name.Length < 10)
                throw new InvalidStudentException("Name must me in range [10..50]");
        }

        private void ValidateClass(int klass)
        {
            if (klass <= 1 || klass > 11)
                throw new InvalidStudentException("Class must me in range [1..11]");
        }

        private void ValidateSsn(int ssn)
        {
            if (ssn.ToString().Length != 9)
                throw new InvalidStudentException("SSN must me exactly 9 digit number");
        }

        [Version(123)]
        private void ValidateGender(char gender)
        {
            if (gender != 'M' && gender != 'F')
                throw new InvalidStudentException("Gender must be either M or F");
        }



        public Student(int age, char gender, string name, int klass, int ssn)
        {
            Validate(name, gender, age, klass, ssn);
            this.age = age;
            this.gender = gender;
            this.name = name;
            this.ssn = ssn;
            this.klass = klass;
        }

        static void Main()
        {
            Student s = new Student(10, 'M', "asd123zsdf", 11, 123456789);
            DateTime a = new DateTime(1989, 6, 30);
            Console.WriteLine("{0:dd.MM.yyyy}", a);
            Console.WriteLine(s);

            Type type = typeof(Student);
            object[] allAttributes =
                type.GetCustomAttributes(false);
            VersionAttribute version =
                (VersionAttribute)allAttributes[0];
            Console.WriteLine(version.Version);

            MethodInfo[] methods = type.GetMethods();
            foreach (MethodInfo method in methods)
            {
                object[] attributes = method.GetCustomAttributes(false);
                foreach (var attrib in attributes)
                {
                    if (attrib is VersionAttribute)
                    {
                        Console.WriteLine(((VersionAttribute)attrib).Version);
                    }
                }
            }
           
        }
    }
}
